package santiago.domain;

import java.io.Serializable;
import java.util.Objects;
import santiago.exception.AlreadyInGameException;
import santiago.exception.InvalidAmountException;
import santiago.exception.InvalidPlayerException;
import santiago.exception.NotEnoughCashException;
import santiago.exception.NotInGameException;

public class Player implements Serializable {

    private String Name;
    private CanalRequest RequestCanal;
    private CanalBlue BlueCanal;
    private int Cash;
    private String GameName;
    private ColorType Color;

    private Player() {
    }

    public Player(String Name) {
        this();
        this.Name = Name;
    }

    /**
     * Decrease the player's cash of the given amount
     *
     * @param Amount
     * @throws InvalidAmountException
     * @throws NotEnoughCashException
     */
    public void pay(int Amount)
            throws InvalidAmountException, NotEnoughCashException {
        if (Amount < 0) {
            throw new InvalidAmountException();
        }
        if (Cash < Amount) {
            throw new NotEnoughCashException();
        }
        Cash -= Amount;
    }

    /**
     * Transfer the given amount to the given player
     *
     * @param Amount
     * @param Player
     * @throws InvalidPlayerException
     * @throws InvalidAmountException
     * @throws NotEnoughCashException
     */
    public void pay(int Amount, Player Player) throws InvalidPlayerException, InvalidAmountException, NotEnoughCashException {
        if (Player == null) {
            throw new InvalidPlayerException();
        }
        this.pay(Amount);
        Player.receiveCash(Amount);
    }

    /**
     * Increase the player's cash of the given amount
     *
     * @param Amount
     * @throws InvalidAmountException
     */
    public void receiveCash(int Amount) throws InvalidAmountException {
        if (Amount < 0) {
            throw new InvalidAmountException();
        }
        Cash += Amount;
    }

    public void joinGame(String GameName, ColorType Color) throws AlreadyInGameException {
        if (this.GameName != null) {
            throw new AlreadyInGameException();
        }
        this.GameName = GameName;
        this.Color = Color;
    }

    public void startGame() {
        RequestCanal = new CanalRequest();
        BlueCanal = new CanalBlue();
        Cash = 0;
    }

    public void leaveGame() {
        GameName = null;
    }

    public String getName() {
        return Name;
    }

    public int getCash() {
        return Cash;
    }

    public String getGameName() throws NotInGameException {
        if (GameName == null) {
            throw new NotInGameException();
        }
        return GameName;
    }

    public boolean isInGame() {
        return GameName != null;
    }

    public ColorType getColor() {
        return Color;
    }

    @Override
    public boolean equals(Object o) {
        if (o instanceof Player) {
            return this.Name.toLowerCase().equals(((Player) o).getName().toLowerCase());
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 67 * hash + Objects.hashCode(this.Name);
        return hash;
    }
}
